package com.alaia.alaiaauth.handler;

import cn.hutool.json.JSONUtil;
import com.alaia.alaiaauth.filter.LoginFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.session.InvalidSessionStrategy;
import org.springframework.security.web.session.SessionInformationExpiredEvent;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.util.Collection;

@Configuration
public class SecurityHandlerConfig {

    /**
     * 匿名用户无权访问401（处理）
     * @return
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint(){
        return new AuthenticationEntryPoint(){
            @Override
            public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                System.out.println("匿名用户无权访问401");
                // 允许跨域
                httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
                // 允许自定义请求头token(允许head跨域)
                httpServletResponse.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
                httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                httpServletResponse.getWriter().print(JSONUtil.toJsonStr(e));
            }
        };
    }

    /**
     * 登录成功jwt
     * @return
     */
    @Bean
    @ConditionalOnProperty(prefix="security.oauth.token.store",name="type" ,havingValue="jwt" ,matchIfMissing=false)
    public AuthenticationSuccessHandler LoginjwtSuccessHandler(){
        return new AuthenticationSuccessHandler(){

            @Override
            public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                System.out.println("登录成功");
                // 允许跨域
                httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
                // 允许自定义请求头token(允许head跨域)
                httpServletResponse.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
                httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                //生成token，并把token加密相关信息缓存，具体请看实现类
                httpServletResponse.getWriter().print(JSONUtil.toJsonStr(authentication));
            }
        };
    }

    /**
     * 登录成功
     * @return
     */
    @Bean
    @ConditionalOnProperty(prefix="security.oauth.token.store",name="type" ,havingValue="jdbc" ,matchIfMissing=false)
    public AuthenticationSuccessHandler LoginSuccessHandler(){
        return new AuthenticationSuccessHandler(){

            @Override
            public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                System.out.println("登录成功");
                // 允许跨域
                httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
                // 允许自定义请求头token(允许head跨域)
                httpServletResponse.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
                httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                httpServletResponse.getWriter().print(JSONUtil.toJsonStr(authentication.getPrincipal()));
            }
        };
    }


    /**
     * 登录失败
     */
    @Bean
    public AuthenticationFailureHandler LoginFailureHandler(){
        return new AuthenticationFailureHandler(){

            @Override
            public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                System.out.println("登陆失败");
                httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
                // 允许自定义请求头token(允许head跨域)
                httpServletResponse.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
                httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                httpServletResponse.getWriter().print(JSONUtil.toJsonStr(e));
            }
        };
    }


    /**
     * 退出登录
     */
    @Bean
    public LogoutSuccessHandler LogoutSuccessHandler(){
        return new LogoutSuccessHandler(){

            @Override
            public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                System.out.println("推出登录");
                // 允许跨域
                httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
                // 允许自定义请求头token(允许head跨域)
                httpServletResponse.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
                httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                httpServletResponse.getWriter().print(JSONUtil.toJsonStr("退出登录成功"));
            }
        };
    }

    /**
     * 会话超时
     */
    @Bean
    public InvalidSessionStrategy InvalidSessionHandler(){
        return new InvalidSessionStrategy(){


            @Override
            public void onInvalidSessionDetected(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
                // 允许跨域
                httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
                // 允许自定义请求头token(允许head跨域)
                httpServletResponse.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
                httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                httpServletResponse.getWriter().print(JSONUtil.toJsonStr("会话超时"));
            }
        };
    }

    /**
     * 同一账号同时登录的用户数受限的处理（顶号）
     */
    @Bean
    public SessionInformationExpiredStrategy SessionInformationExpiredHandler(){
        return new SessionInformationExpiredStrategy(){

            @Override
            public void onExpiredSessionDetected(SessionInformationExpiredEvent sessionInformationExpiredEvent) throws IOException, ServletException {
                // 允许跨域
                sessionInformationExpiredEvent.getResponse().setHeader("Access-Control-Allow-Origin", "*");
                // 允许自定义请求头token(允许head跨域)
                sessionInformationExpiredEvent.getResponse().setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
                sessionInformationExpiredEvent.getResponse().setHeader("Content-type", "application/json;charset=UTF-8");
                sessionInformationExpiredEvent.getResponse().getWriter().print(JSONUtil.toJsonStr("登录人数超限"));
            }
        };
    }

    /**
     * 没有权限处理
     */
    @Bean
    public AccessDeniedHandler LoginUserAccessDeniedHandler(){
        return new AccessDeniedHandler(){

            @Override
            public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
                // 允许跨域
                httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
                // 允许自定义请求头token(允许head跨域)
                httpServletResponse.setHeader("Access-Control-Allow-Headers", "token, Accept, Origin, X-Requested-With, Content-Type, Last-Modified");
                httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
                httpServletResponse.getWriter().print(JSONUtil.toJsonStr("没有权限访问当前接口"));
            }
        };
    }
}
